package com.sencorsta.ids.core.tcp.socket.protocol;

import java.util.Arrays;

import com.sencorsta.ids.core.configure.GlobalConfigure;
import com.sencorsta.ids.core.configure.TypeProtocol;
import com.sencorsta.ids.core.configure.TypeSerialize;

import com.sencorsta.ids.core.tcp.socket.NetHandler;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;

/**
 * 　　* @description: RPC消息
 * 　　* @author TAO
 * 　　* @date 2019/6/12 17:19
 */
public class RpcMessage extends BaseMessage {

    // public short serverType;//服务器类型
    public short serializeType;// 序列化类型
    public String method;// 调用方法
    public String userId;
    public Long msgId;
    public String errMsg;
    public byte[] data;// 数据

    public Channel channel;

    public RpcMessage(short typeProtocol) {
        this();
        header.type = typeProtocol;
    }

    public RpcMessage() {
        data = new byte[0];
        msgId = 0l;
        errMsg = "";
        userId = "";
        method = "";
    }

    /**
     * 是否已关闭
     */
    public boolean isChannelClosed() {
        return channel == null || !channel.isActive();
    }

    @Override
    public void encodeBody() {
        body = new Body(10);
        body.content.writeShort(serializeType);
        body.writeString(method);
        body.writeString(userId);
        body.content.writeLong(msgId);
        body.writeString(errMsg);
        body.content.writeBytes(data);
        header.length = body.content.readableBytes();
    }

    @Override
    public void decodeBody() {
        serializeType = body.content.readShort();
        method = body.readString();
        userId = body.readString();
        msgId = body.content.readLong();
        errMsg = body.readString();
        data = new byte[body.content.readableBytes()];
        body.content.readBytes(data);
    }

    public String toStringPlus() {
        switch (serializeType) {
            case TypeSerialize.TYPE_JSON:
                return "header:[" + header + "]" + " body:[" + "serializeType:" + serializeType + " method:" + method + " data:" + new String(data, GlobalConfigure.UTF_8) + "]";
            case TypeSerialize.TYPE_STRING:
                return "header:[" + header + "]" + " body:[" + "serializeType:" + serializeType + " method:" + method + " data:" + new String(data, GlobalConfigure.UTF_8) + "]";
            case TypeSerialize.TYPE_BYTEARR:
                return "header:[" + header + "]" + " body:[" + "serializeType:" + serializeType + " method:" + method + " data:" + Arrays.toString(data) + "]";
            case TypeSerialize.TYPE_PROTOBUF:
                return "header:[" + header + "]" + " body:[" + "serializeType:" + serializeType + " method:" + method + " data:" + Arrays.toString(data) + "]";
            default:
                break;
        }
        return "header:[" + header + "]" + " body:[" + "serializeType:" + serializeType + " method:" + method + " data:" + "🐷未知协议🐷" + "]";
    }

    public String toString() {
        switch (serializeType) {
            case TypeSerialize.TYPE_JSON:
                return "{[" + header + "]" + "[TYPE_JSON]" + method + "}";
            case TypeSerialize.TYPE_STRING:
                return "{[" + header + "]" + "[TYPE_STRING]+" + method + "}";
            case TypeSerialize.TYPE_BYTEARR:
                return "{[" + header + "]" + "[TYPE_BYTEARR]" + method + "}";
            case TypeSerialize.TYPE_PROTOBUF:
                return "{[" + header + "]" + "[TYPE_PROTOBUF]" + method + "}";
            default:
                break;
        }
        return "{[" + header + "]" + "[未知协议🐷]" + method + "}";
    }

    public <T> T getAttr(AttributeKey<T> att) {
        return channel.attr(att).get();
    }

    public <T> void setAttr(AttributeKey<T> att, T value) {
        channel.attr(att).set(value);
    }


}
